using System;
using System.Collections.Generic;
using System.Text;
using Domain.Core;
using NUnit.Framework;
using TestUtil;
using TestUtil.Equality;

namespace Domain.Core.Tests
{
    [TestFixture]
    public class MoneyEqualityTests
    {
        # region Constants

        const decimal FirstAmount = 503.5m;
        const decimal SecondAmount = 502.9m;

        # endregion

        # region Tests - Equality

        [Test]
        public void IdentifiesWhenEqual()
        {
            Money first = CreateValueInPounds(FirstAmount);
            Money second = CreateValueInPounds(FirstAmount);

            Assert.IsTrue(first == second, "== is not behaving correctly.");
            Assert.IsFalse(first != second, "!= is not behaving correctly.");

            Assert.IsTrue(first.Equals(second), "The equals method is not behaving correctly.");
        }

        [Test]
        public void IdentifiesWhenNotEqual()
        {
            Money first = CreateValueInPounds(FirstAmount);
            Money second = CreateValueInPounds(SecondAmount);

            Assert.IsFalse(first == second, "== is not behaving correctly.");
            Assert.IsTrue(first != second, "!= operator is not working.");

            Assert.IsFalse(first.Equals(second), "The equals method is not behaving correctly.");
        }

        [Test]
        public void SymmetricEqualityWhenEqualTest()
        {
            Money first = CreateValueInPounds(FirstAmount);
            Money second = CreateValueInPounds(FirstAmount);

            Assert.IsTrue(first == second, "First and second should have been equal.");
            Assert.IsTrue(second == first, "Second and first should have been equal.");
        }

        [Test]
        public void SymmetricEqualityWhenNotEqualTest()
        {
            Money first = CreateValueInPounds(FirstAmount);
            Money second = CreateValueInPounds(SecondAmount);

            Assert.IsFalse(first == second, "First and second should NOT have been equal.");
            Assert.IsFalse(second == first, "Second and first should NOT have been equal.");
        }

        [Test]
        public void TransitiveEqualityTest()
        {
            CreateTestObjectCallback<Money> callback = delegate { return CreateValueInPounds(FirstAmount); };

            new TransitiveEqualityTestHelper<Money>(callback).PerformTest();
        }

        #endregion

        # region Support Methods

        private Money CreateValueInPounds(decimal amount)
        {
            return new Money(MoneyCurrency.PoundSterling, amount);
        }

        private Money CreateValueIFrancs()
        {
            return new Money(MoneyCurrency.FrancCongolais, (decimal)534.99);
        }

        # endregion
    }
}